package com.magenta.maxoptra.gis;


import com.magenta.maxoptra.gis.SQL.*;
import com.magenta.maxoptra.gis.SQL.Indexes;
import com.magenta.maxoptra.gis.commons.StringUtils;

import javax.persistence.Column;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import java.io.Serializable;
import java.util.Date;

import static com.magenta.maxoptra.gis.GisConstants.MAX_LATITUDE_ACCURACY;
import static com.magenta.maxoptra.gis.GisConstants.MAX_LONGITUDE_ACCURACY;

/**
 * User: Sychin
 * Date: 23.10.2008
 * Time: 12:13:01
 */
public class GeoAddress implements Serializable {
    //TODO ivictus: add unit of measure for longitude and latitude
    /**
     * Unique ID for serialization/deserialization.
     */
    private static final long serialVersionUID = 3483814227679658613L;

    @Column(columnDefinition = "decimal(" + (int) (MAX_LATITUDE_ACCURACY + 3) + "," + MAX_LATITUDE_ACCURACY + ")")
    private Double latitude;
    @Column(columnDefinition = "decimal(" + (int) (MAX_LONGITUDE_ACCURACY + 3) + "," + MAX_LONGITUDE_ACCURACY + ")")
    private Double longitude;
    @SQL.Charset
    @Column(precision = 255)
    private String house;
    @Charset
    @Column(precision = 255)
    private String street;
    @Charset
    @Column(precision = 255)
    private String city;
    @Charset
    @Column(precision = 255)
    private String state;
    @Charset
    @Column(precision = 255)
    private String country;
    @Charset
    @Column(precision = 64)
    private String zip;
    @Charset
    @Column(precision = 255)
    private String info;
    @Charset
    @Column(precision = 255)
    private String county;
    @Charset
    @Column(precision = 255)
    private String district;
    @Column(columnDefinition = "integer")
    private Integer speedLimit;
    @Column (columnDefinition = "tinyint")
    private Boolean isAccurate;



    /**
     * Request date.
     */
    @Indexes("request_date_index")
    @Temporal(TemporalType.TIMESTAMP)
    private Date timestamp;

    public GeoAddress() {
    }

    public String getCounty() {
        return county;
    }

    public Boolean getIsAccurate() {
        return isAccurate;
    }

    public void setIsAccurate(Boolean isAccurate) {
        this.isAccurate = isAccurate;
    }

    public void setCounty(String county) {
        this.county = county;
    }

    public String getDistrict() {
        return district;
    }

    public void setDistrict(String district) {
        this.district = district;
    }

    public String getZip() {
        return zip;
    }

    public void setZip(String zip) {
        this.zip = zip;
    }

    public Double getLongitude() {
        return longitude;
    }

    public void setLongitude(Double longitude) {
        this.longitude = longitude;
    }

    public Double getLatitude() {
        return latitude;
    }

    public void setLatitude(Double latitude) {
        this.latitude = latitude;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        if ("Unknown".equals(country)) {
            return "";
        }
        if (StringUtils.isNotEmpty(house)) {
            append(stringBuilder, !"-1".equals(house) ? house : "");
        }
        append(stringBuilder, street);
        append(stringBuilder, city);
        append(stringBuilder, state);
        append(stringBuilder, zip);
        append(stringBuilder, info);
        stringBuilder = new StringBuilder(stringBuilder.toString().trim());
        if (StringUtils.isNotEmpty(country)) {
            stringBuilder.append(", ").append(country);
        }
        return stringBuilder.toString();
    }

    private void append(StringBuilder stringBuilder, String value) {
        if (!isEmpty(value)) {
            stringBuilder.append(value).append(" ");
        }
    }

    private boolean isEmpty(String text) {
        return text == null || text.trim().length() == 0;
    }


    public String getHouse() {
        return house;
    }

    public void setHouse(String house) {
        this.house = house;
    }

    public int getLongitudeAccuracy() {
        return MAX_LONGITUDE_ACCURACY;
    }

    public int getLatitudeAccuracy() {
        return MAX_LATITUDE_ACCURACY;
    }

    /**
     * Date of request with precision by second.
     *
     * @return
     */
    public Date getTimestamp() {
        return timestamp;
    }

    /**
     * As array representation.
     */
    public Object[] toArray() {
        return new Object[]{latitude, longitude, house, street, city, state, country, zip, info, county, district,
                speedLimit, isAccurate};
    }

    public Integer getSpeedLimit() {
        return speedLimit;
    }

    public void setSpeedLimit(Integer speedLimit) {
        this.speedLimit = speedLimit;
    }
}